import os
import re
import subprocess
import sys

path = os.path.dirname(os.path.dirname(__file__))
sys.path.append(path)
from base.user_log import log
from QuickerBeta.util2 import OpYaml


class Cmds:
    check_5037 = 'netstat -ano | findstr 5037'
    check_port = 'netstat -ano | findstr {}'
    devices = 'adb devices'
    set_tcpip = 'adb -s {} tcpip {}'
    ipconfig = 'adb -s {} shell ifconfig wlan0'
    connect = 'adb connect {}'
    dis_connect = 'adb disconnect {}'
    a01 = 'adb tcpip 5503'

    @staticmethod
    def execute(command, get_res=False, timeout=4):
        log.debug('执行cmd：{}'.format(command))
        p = subprocess.Popen(command, stdout=subprocess.PIPE, shell=True)
        try:
            p.wait(timeout)
        except subprocess.TimeoutExpired:
            p.kill()
            msg = '超时！请检查命令参数是否正确: \n{}'.format(command)
            raise SystemExit(msg)
        reads = str(p.stdout.read(), encoding='utf-8')
        read_lines = [i for i in reads.split('\r\n') if i]
        log.debug(read_lines)
        if get_res:
            return reads
        return read_lines


class Connect(Cmds):
    op_yaml = OpYaml()

    @classmethod
    def print_record(cls):
        print('历史连接设备：')
        for i in cls.op_yaml.data_list:
            print(cls.connect.format(i))

    def __new__(cls, *args, **kwargs):
        cls.print_record()
        a01 = input('\n需要连接usb的设备吗？（y/n）')
        if 'y' in a01:
            return super().__new__(cls, *args, **kwargs)
        else:
            raise SystemExit

    def __init__(self):
        log.debug('准备开始远程连接')
        self.remote_list = []
        self.usb_list = []
        self.port_list = []
        self.ip_list = []

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        msg = '需要查看当前的连接情况吗？(y/n)'
        key = input(msg)
        if 'y' in key:
            res = self.execute(self.devices, get_res=True)
            print('\n' + res)
        log.close()

    def __get_devicesName(self):
        log.debug('获取devices列表')
        res_li = self.execute(self.devices, timeout=6)
        for i in res_li:
            if '\tdevice' in i:
                self.__init_attr(i)  # 处理devices
        log.debug(f'\n usb连接有：{self.usb_list}'
                  f'远程连接有：{self.remote_list}；端口有：{self.port_list}', )
        # 检查是否存在usb连接
        if not self.usb_list:
            print('错误：不存在usb连接，请检查设备\n')
            raise SystemExit

    def __init_attr(self, i):
        # 把devices分类到remote、usb、和post列表中
        name = i.split('\t')[0]
        if ':' in i:
            self.remote_list.append(name)
            ip, port = name.split(':')
            self.ip_list.append(ip)
            self.port_list.append(port)
        else:
            self.usb_list.append(name)

    def exe_tcpIp(self, name_li, port):
        log.debug('设置tcpip端口')
        name = name_li[0]
        cmd = self.set_tcpip.format(name, port)
        self.execute(cmd)
        return None

    def exe_connect(self, ip, port):
        log.debug('执行远程连接')
        ip_port = f'{ip}:{port}'
        cmd = self.connect.format(ip_port)
        res = self.execute(cmd, get_res=True)
        return res

    def get_ip(self, usb_li) -> str:
        log.debug('获取ip地址')
        cmd = self.ipconfig.format(usb_li[0])
        res_li = self.execute(cmd)
        ip = None
        for i in res_li:
            if 'inet addr' in i:
                ip = re.search(r'inet addr:(.+?)\s', i)[1]
        log.debug(f'ip地址为: {ip}')
        if ip in self.ip_list:
            msg = '当前的usb设备已经远程连接了，请拔掉usb线，换下一台！'
            raise SystemExit(msg)
        return ip

    def get_port(self, port):
        step = 1
        for i in range(1, 10):
            if str(port) in self.port_list:
                port += step
        log.debug(f'获取不重复的端口号：{port}')
        return port

    def record_connect(self):
        # 记录连接过的
        remote_li = self.op_yaml.data_list
        for i in self.remote_list:
            if i not in remote_li:
                remote_li.append(i)
        self.op_yaml.write()

    def main(self):
        self.__get_devicesName()
        port = 5501
        usb_list = self.usb_list
        ip = self.get_ip(usb_list)  # 获取ip和port
        port = self.get_port(port)
        res = self.exe_connect(ip, port)  # 首先直接远程连接
        self.main_02(res, ip, port, usb_list)  # 如果直接连接不了，再执行tcpip

    def main_02(self, res, ip, port, res_li):
        if 'connected' in res:
            print(f'{res}连接成功!')
        elif 'no such device' or 'cannot connect' in res:
            self.exe_tcpIp(res_li, port)
            res = self.exe_connect(ip, port)
            print(f'{res}连接成功!')
        else:
            return print(f'{res}连接失败!')
        self.remote_list.append(f'{ip}:{port}')
        self.record_connect()


# @click.command()
# @click.option('-m', default='', help='')
"""
0. 首先打印历史连接设备，并提示是否需要连接当前usb设备（y/n）
    如果不需要，可以根据历史连接设置直接发起无线连接
1. 获取设备信息：，获取usb连接的list、远程连接的list；远程连接又分解为ip列表和port列表
    如果不存在usb连接，则【提示并中断】
2. 获取ip地址：获取usb对应的ip地址（如果存在usb）
    如果该ip已经远程连接了，则【提示并中断】
3. 连接：拼接字符串（ip、默认port），尝试直接连接
    如果连接失败，执行4；然后再次连接；
4. 创建tcpip端口：（如果该ip还没远程连接）
    通过port列表，来得到一个新端口（遍历port列表，从5501开始，每次+1；直到不存在列表中为止）
    执行创建tcpip端口
"""

# note 获取port时，应该把历史的远程连接也加入到port中
if __name__ == '__main__':
    with Connect() as con:
        con.main()
